package com.itheima.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.itheima.constant.RedisConstant;
import com.itheima.dao.CheckGroupDao;
import com.itheima.dao.CheckItemDao;
import com.itheima.dao.SetmealDao;
import com.itheima.entity.PageResult;
import com.itheima.entity.QueryPageBean;
import com.itheima.pojo.CheckGroup;
import com.itheima.pojo.CheckItem;
import com.itheima.pojo.Setmeal;
import com.itheima.service.SetmealService;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
import redis.clients.jedis.JedisPool;

import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service(interfaceClass = SetmealService.class)
@Transactional
public class SetmealServiceImpl implements SetmealService {

    @Autowired
    private SetmealDao setmealDao;

    @Autowired
    private JedisPool jedisPool;

    @Autowired
    private FreeMarkerConfigurer freeMarkerConfigurer;

    @Value("${out_put_path}")
    private String out_put_path;

    @Override
    public void add(Setmeal setmeal,Integer[] checkgroupIds) {
        setmealDao.add(setmeal);
        Integer id = setmeal.getId();
        setSetmealAndCheckgroup(id,checkgroupIds);

        //将要存入数据库中的img路径保持到另一个redis中
        jedisPool.getResource().sadd(RedisConstant.SETMEAL_PIC_DB_RESOURCES,setmeal.getImg());

        //新增套餐后需要生产静态页面
        generateMobileStaticHtml();
        System.out.println("----------------------------------------------");

    }

    //生成静态页面
    public void generateMobileStaticHtml(){
        //准备模板文件中所需的数据
        List<Setmeal> setmealList=this.findAll();

        //生成套餐列表静态页面
        generateMobileSetmealListHtml(setmealList);

        //生成套餐详细静态页面（多个）
        generateMobileSetmeamlListDetailHtml(setmealList);
        
    }

    //生成套餐列表静态页面
    public void generateMobileSetmealListHtml(List<Setmeal> setmealList){
        HashMap<String, Object> dataMap = new HashMap<>();
        dataMap.put("setmealList",setmealList);
        this.generateHtml("mobile_setmeal.ftl","m_setmeal.html",dataMap);

    }

    //生成套餐详细静态页面（多个）
    public void generateMobileSetmeamlListDetailHtml(List<Setmeal> list){
        for (Setmeal setmeal : list) {
            Setmeal setmeal_findById = findAllById(setmeal.getId());

            HashMap dataMap = new HashMap();
            dataMap.put("setmeal",setmeal_findById);
            generateHtml("mobile_setmeal_detail.ftl","setmeal_detail_"+setmeal_findById.getId()+".html",dataMap);
        }
    }


    //用于生成静态页面
    public void generateHtml(String templateName, String htmlPageName , Map<String,Object> dataMap) {

        FileWriter out = null;
        try {
            Configuration configuration = freeMarkerConfigurer.getConfiguration();
            Template template = configuration.getTemplate(templateName);



            out = new FileWriter(new File(out_put_path + "/" + htmlPageName));

            String dir = out_put_path + "/" + htmlPageName;

            OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(dir), "UTF-8");
            PrintWriter printWriter = new PrintWriter(writer);

            //输出文件
            template.process(dataMap, printWriter);

        } catch (IOException e) {
            e.printStackTrace();
        } catch (TemplateException e) {
            e.printStackTrace();
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }






//-------------------------------------------//


    //条件分页查询
    @Override
    public PageResult findPage(QueryPageBean queryPageBean) {
        Integer currentPage = queryPageBean.getCurrentPage();
        Integer pageSize = queryPageBean.getPageSize();
        String queryString = queryPageBean.getQueryString();
        PageHelper.startPage(currentPage,pageSize);


        Page<Setmeal> page= setmealDao.findPage(queryString);

        return new PageResult(page.getTotal(),page.getResult());
    }

    //根据id完成级联删除
    @Override
    public void delete(Integer id) {
        //先删除中间表的关系数据
        setmealDao.deleteBySetmealAndCheckgroup(id);

        //查询该id的img
        String img = setmealDao.findById(id).getImg();
        //删除redis的缓存缓存
        if (img!=null){
            jedisPool.getResource().sadd(RedisConstant.SETMEAL_PIC_RESOURCES,img);
            jedisPool.getResource().srem(RedisConstant.SETMEAL_PIC_DB_RESOURCES,img);
        }
        //再删除setmeal表的数据
        setmealDao.deleteById(id);
    }


    @Autowired
    private CheckGroupDao checkGroupDao;

//    根据id查询单条数据
    @Override
    public Setmeal findById(Integer id) {
        Setmeal setmeal = setmealDao.findById(id);
        List<CheckGroup> list = checkGroupDao.findAll();
        setmeal.setCheckGroups(list);
        return setmeal;
    }

    //回显数据的复选框
    @Override
    public Integer[] findSetmealByCheckGroupId(Integer id) {
        return setmealDao.findSetmealByCheckGroupId(id);
    }

    //修改体检表数据
    @Override
    public void edit(Setmeal setmeal, Integer[] checkgroupIds) {

        String img = setmealDao.findById(setmeal.getId()).getImg();

        jedisPool.getResource().srem(RedisConstant.SETMEAL_PIC_DB_RESOURCES,img);

        //1.首先修改t_setmeal的数据
        setmealDao.edit(setmeal);
        //2. 根据id删除中间表的数据
        setmealDao.deleteBySetmealAndCheckgroup(setmeal.getId());
        //3. 根据数组添加中间表的数据
        setSetmealAndCheckgroup(setmeal.getId(),checkgroupIds);

        //修改之后的图片名字存入数据库
        jedisPool.getResource().sadd(RedisConstant.SETMEAL_PIC_DB_RESOURCES,setmeal.getImg());

    }


    //查询所有套餐
    @Override
    public List<Setmeal> findAll() {

        return setmealDao.findAll();
    }


    @Autowired
    private CheckItemDao checkItemDao;
    //根据id查询3个表的数据
    @Override
    public Setmeal findAllById(Integer id) {
        //根据id查询setmeal表的数据
        Setmeal setmeal = setmealDao.findById(id);
        //根据setmeal_id查询中间表checkgroup_id的集合
        Integer[] CheckGroupIds = setmealDao.findSetmealByCheckGroupId(id);
        //创建类型为CheckGroup的集合
        List<CheckGroup> checkGroupList = new ArrayList<CheckGroup>();
        //遍历数组
        for (Integer checkGroupId : CheckGroupIds) {
            //根据checkGroupId查询checkgroup表的数据
            CheckGroup checkgroup = checkGroupDao.findById(checkGroupId);
            //创建类型为CheckItem的集合
            ArrayList<CheckItem> checkItemsList = new ArrayList<>();
            //根据checkGroupId查询checkitem_id的集合
            List<Integer> checkItemIds = checkGroupDao.findCheckItemIdsByCheckGroupId(checkGroupId);
            //遍历checkitem_id集合
            for (Integer checkItemId : checkItemIds) {
                //根据checkitem_id查询checkitem数据
                CheckItem checkItem = checkItemDao.findById(checkItemId);
                //添加checkitem数据到  类型为CheckItem的集合
                checkItemsList.add(checkItem);
            }
            //将集合到 checkItemsList 到 checkgroup
            checkgroup.setCheckItems(checkItemsList);

            //添加checkgroup数据到  类型为  checkGroupList 的集合
            checkGroupList.add(checkgroup);
        }
        // checkGroupList数据添加到 setmeal
        setmeal.setCheckGroups(checkGroupList);

        return setmeal;
    }

    //预约套餐占比数据
    @Override
    public List<Map<String, Object>> findSetmealCount() {
        return setmealDao.findSetmealCount();
    }


    //添加中间表的数据
    private void setSetmealAndCheckgroup(Integer checkGroupId, Integer[] checkgroupIds) {

        if (checkgroupIds != null && checkgroupIds.length > 0) {
            for (Integer checkItemId : checkgroupIds) {
                HashMap<String, Integer> map = new HashMap<>();
                map.put("setmeal_id", checkGroupId);
                map.put("checkgroup_id", checkItemId);
                setmealDao.setSetmealAndCheckgroup(map);
            }

        }

    }

}
